/**
 * <h3>SchoolServiceImpl</h3>
 * <p> 学校服务实现类 </p>
 *
 * <h3>功能描述</h3>
 * <p> 实现了 {@link ISchoolService} 接口中定义的学校信息增删改查业务逻辑 </p>
 * <p> 通过调用 {@link SchoolMapper} 完成对数据库的操作，支持条件查询、按ID查询、更新、新增和删除等操作 </p>
 *
 * <h3>元数据</h3>
 * <ul>
 *    <li> 作者：郭强</li>
 *    <li> 创建日期：2025年05月06日 21:20:00</li>
 * </ul>
 *
 * <h3>其他信息</h3>
 * <ul>
 *    <li> 参考链接：<a href="https://example.com">官方网页</a></li>
 *    <li> 示例代码：{@code new SchoolServiceImpl()} </li>
 * </ul>
 *
 * @apiNote 该类基于 MyBatis Plus 的 ServiceImpl 实现，需确保 SchoolMapper 正确注入
 * @implSpec 继承自 {@link ServiceImpl<SchoolMapper, School>} 并实现 {@link ISchoolService} 接口
 * @since 1.0.0
 */

package com.dnndo.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnndo.common.utils.bean.BeanDtoVoUtil;
import com.dnndo.system.domain.School;
import com.dnndo.system.domain.dto.*;
import com.dnndo.system.domain.vo.ApiSchoolEnVO;
import com.dnndo.system.domain.vo.ApiSchoolZhVO;
import com.dnndo.system.domain.vo.CityVO;
import com.dnndo.system.domain.vo.SchoolRelatedInfoVO;
import com.dnndo.system.mapper.SchoolMapper;
import com.dnndo.system.service.ISchoolService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 学校服务实现类
 */
@Service
public class SchoolServiceImpl extends ServiceImpl<SchoolMapper, SchoolDTO> implements ISchoolService {

  private final SchoolMapper schoolMapper;

  @Autowired
  public SchoolServiceImpl(SchoolMapper schoolMapper) {
    this.schoolMapper = schoolMapper;
  }

  /**
   * 查询符合条件的学校信息列表
   * 逻辑说明：
   * 1. 根据dto参数中的条件（如学校名称、类型、省份等）查询学校信息。
   * 2. 直接调用Mapper的selectSchoolList方法，返回结果。
   *
   * @param dto 查询条件
   * @return List<School> 学校信息列表
   */
  @Override
  public List<School> selectSchoolList(SchoolDTO dto) {
    return schoolMapper.selectSchoolList(dto);
  }

  @Override
  public List<School> selectSchoolNameList(SchoolDTO dto) {
    return schoolMapper.selectSchoolNameList(dto);
  }

  /**
   * 查询已收录学校logo列表
   * 逻辑说明：
   * 1. 根据dto参数中的条件查询已收录学校logo信息。
   * 2. 直接调用Mapper的selectSchoolLogoList方法，返回结果。
   *
   * @param dto 查询条件
   * @return List<School> 学校logo信息列表
   */
  @Override
  public List<School> selectSchoolLogoList(SchoolDTO dto) {
    return schoolMapper.selectSchoolLogoList(dto);
  }

  /**
   * 根据学校ID查询学校详细信息
   * 逻辑说明：
   * 1. 通过schoolId查询学校详细信息。
   *
   * @param schoolId 学校ID
   * @return SchoolDTO 学校详细信息
   */
  @Override
  public SchoolDTO selectSchoolListById(Long schoolId) {
    return schoolMapper.selectSchoolListById(schoolId);
  }

  /**
   * 更新学校信息
   * 逻辑说明：
   * 1. 根据schoolDTO中的schoolId更新学校信息。
   *
   * @param schoolDTO 学校数据对象
   * @return int 受影响的记录数
   */
  @Override
  public int updateSchoolById(SchoolDTO schoolDTO) {
    return schoolMapper.updateSchoolById(schoolDTO);
  }

  /**
   * 新增学校信息
   * 逻辑说明：
   * 1. 插入新的学校数据，需保证schoolDTO字段完整。
   *
   * @param schoolDTO 学校数据对象
   * @return int 受影响的记录数
   */
  @Override
  public int insertSchool(SchoolDTO schoolDTO) {
    if (schoolMapper.existsBySchoolName(schoolDTO.getSchoolName()) > 0) {
      throw new RuntimeException("学校已存在");
    }
    return schoolMapper.insertSchool(schoolDTO);
  }

  /**
   * 删除指定ID的学校信息
   * 逻辑说明：
   * 1. 根据schoolId删除对应学校信息。
   *
   * @param schoolId 学校ID
   * @return int 受影响的记录数
   */
  @Override
  public int deleteSchoolById(Integer schoolId) {
    return schoolMapper.deleteSchoolById(schoolId);
  }

  /**
   * 下架指定ID的学校信息
   * 逻辑说明：
   * 1. 根据schoolId下架对应学校信息。
   *
   * @param schoolId 学校ID
   * @return int 受影响的记录数
   */
  @Override
  public int downSchoolById(Integer schoolId) {
    return schoolMapper.downSchoolById(schoolId);
  }

  /**
   * 获取学校相关的主管部门、院校特征和办学层次信息（支持中英文）
   * 逻辑说明：
   * 1. 根据language参数分支，分别查询中文或英文的主管部门、特征、层次信息。
   * 2. 通过processCharacteristics方法对特征字段进行归并和去重。
   * 3. 组装SchoolRelatedInfoVO返回。
   *
   * @param language 语言类型（zh/en）
   * @return SchoolRelatedInfoVO 相关信息
   */
  @Override
  public SchoolRelatedInfoVO getSchoolRelatedInfo(String language) {
    SchoolRelatedInfoVO result = new SchoolRelatedInfoVO();
    if ("zh".equals(language)) {
      result.setCompetentDepartment(processCharacteristics(schoolMapper.selectCharacteristicsListZh()));
      result.setCharacteristic(schoolMapper.selectLevelListZh());
      result.setManager(schoolMapper.selectCompetentDepartmentListZh());
    } else if ("en".equals(language)) {
      result.setCompetentDepartment(processCharacteristics(schoolMapper.selectCharacteristicsListEn()));
      result.setCharacteristic(schoolMapper.selectLevelListEn());
      result.setManager(schoolMapper.selectCompetentDepartmentListEn());
    }
    return result;
  }

  /**
   * 处理 characteristics 字段，将其转换为统一的列表形式
   * 逻辑说明：
   * 1. 遍历原始特征字符串，按分隔符拆分，去重归并。
   * 2. 返回排序后的特征列表。
   *
   * @param list 原始特征字符串列表
   * @return List<String> 处理后的特征列表
   */
  public List<String> processCharacteristics(List<String> list) {
    Set<String> allCharacteristics = new HashSet<>();
    for (String characteristics : list) {
      if (characteristics != null && !characteristics.isEmpty()) {
        String[] parts = characteristics.split("[,、]");
        allCharacteristics.addAll(Arrays.asList(parts));
      }
    }
    List<String> result = new ArrayList<>(allCharacteristics);
    Collections.sort(result);
    return result;
  }

  /**
   * 查询省份城市列表（支持中英文）
   * 逻辑说明：
   * 1. 根据language参数分支，分别查询中文或英文的省份城市信息。
   * 2. 对每个省份的城市字符串进行拆分，组装为CityVO列表。
   * 3. 返回组装好的省份城市树结构。
   *
   * @param language 语言类型（zh/en）
   * @return List<ProvinceDTO> 省份城市树
   */
  @Override
  public List<ProvinceDTO> getProvinceCityListDTO(String language) {
    try {
      List<ProvinceDTO> provinceCityList = "zh".equals(language) ?
        schoolMapper.selectProvinceCityGroupedByProvinceZhVO() :
        schoolMapper.selectProvinceCityGroupedByProvinceEnVO();
      for (ProvinceDTO provincedto : provinceCityList) {
        provincedto.setValue(provincedto.getProvince());
        provincedto.setLabel(provincedto.getProvince());
        if (provincedto.getCities() != null && !provincedto.getCities().isEmpty()) {
          String[] citiesArray = provincedto.getCities().split(",");
          List<CityVO> cities = Arrays.stream(citiesArray)
            .map(city -> {
              CityVO cityVO = new CityVO();
              cityVO.setValue(city);
              cityVO.setLabel(city);
              return cityVO;
            })
            .collect(Collectors.toList());
          provincedto.setChildren(cities);
        }
      }
      return provinceCityList;
    } catch (Exception e) {
      throw new RuntimeException("查询省份城市列表失败: " + e.getMessage(), e);
    }
  }

  /**
   * 获取校徽收录统计信息
   * 逻辑说明：
   * 1. 查询校徽收录的统计数据（如各年份、各类型数量等）。
   * 2. 解析schoolDate字符串为List<Map<String, Object>>结构，便于前端展示。
   * 3. 若无数据则返回空对象。
   *
   * @return SchoolStatisticsDTO 校徽收录统计信息
   */
  @Override
  public SchoolStatisticsDTO getSchoolStatistics() {
    SchoolStatisticsDTO statistics = schoolMapper.selectSchoolStatistics();
    if (statistics != null && statistics.getSchoolDate() != null) {
      // 解析 schoolData 字符串
      String schoolDataString = statistics.getSchoolDate();
      String[] dataPairs = schoolDataString.split(",");
      // 构建 List<Map<String, Object>>
      List<Map<String, Object>> schoolDataList = Arrays.stream(dataPairs)
        .map(pair -> {
          String[] keyValue = pair.split(":");
          Map<String, Object> item = new HashMap<>();
          item.put("name", keyValue[0]);
          item.put("value", Integer.parseInt(keyValue[1]));
          return item;
        })
        .collect(Collectors.toList());
      // 赋值给 SchoolStatisticsDTO
      statistics.setSchoolData(schoolDataList);
    }
    return statistics != null ? statistics : new SchoolStatisticsDTO();
  }

  /**
   * 查询校徽收录信息（支持中英文）
   * 逻辑说明：
   * 1. 根据dto.language分支，分别查询中文或英文校徽收录信息。
   * 2. 处理特征字段，按语言分割为数组，便于前端展示。
   *
   * @param dto 查询参数，包含语言类型
   * @return List<SchoolOfficialDTO> 校徽收录信息列表
   */
  @Override
  public List<SchoolOfficialDTO> schoolBadgeOfficial(SchoolOfficialDTO dto) {
    if (dto.getCharacteristic().equals("全部") || dto.getCharacteristic().equals("All")){
      dto.setCharacteristic("");
    }
    if (dto.getLevel().equals("全部") || dto.getLevel().equals("All")){
      dto.setLevel("");
    }
    String language = dto.getLanguage();
    List<SchoolOfficialDTO> result;
    if ("zh".equals(language)) {
      result = schoolMapper.selectSchoolLogoListZh(dto);
    } else if ("en".equals(language)) {
      result = schoolMapper.selectSchoolLogoListEn(dto);
    } else {
      throw new IllegalArgumentException("未知语言");
    }
    // 处理 characteristics 字段
    for (SchoolOfficialDTO item : result) {
      if ("zh".equals(language)) {
        // 处理中文特征字段
        String characteristic = item.getCharacteristic();
        if (characteristic != null && !characteristic.isEmpty()) {
          String[] parts = characteristic.split("[,、]");
          item.setCharacteristics(parts);
        } else {
          item.setCharacteristics(new String[0]);
        }
      }
      if ("en".equals(language)) {
        // 处理英文特征字段
        String characteristicEn = item.getCharacteristicEn();
        if (characteristicEn != null && !characteristicEn.isEmpty()) {
          String[] parts = characteristicEn.split("[,、]");
          item.setCharacteristicsEn(parts);
        } else {
          item.setCharacteristicsEn(new String[0]);
        }
      }
    }
    return result;
  }

  /**
   * 获取大学相关的所有信息（中文版）
   * 逻辑说明：
   * 1. 查询大学相关的所有信息（如校徽、官网、校园大使等），仅取第一个结果。
   * 2. 处理特征、活动、校徽等字段，去除空值，组装VO返回。
   *
   * @param dto 查询参数
   * @return ApiSchoolZhVO 大学信息（中文）
   */
  @Override
  public ApiSchoolZhVO getSchoolInfoZh(ApiSchoolDTO dto) {
    List<ApiSchoolDTO> dtolist = schoolMapper.selectSchoolApiZh(dto);
    if (dtolist.isEmpty()) {
      return null;
    }
    // 只取第一个结果
    ApiSchoolDTO apiSchoolDTO = dtolist.get(0);
    // 过滤校园大使，仅保留ambassador为true的
    List<ApiSchoolDTO.CampusAmbassador> ambassadors = apiSchoolDTO.getCampusAmbassadors();
    List<ApiSchoolDTO.CampusAmbassador> filteredList = new ArrayList<>();
    for (ApiSchoolDTO.CampusAmbassador ambassador : ambassadors) {
      if ("true".equals(ambassador.getAmbassador())) {
        filteredList.add(ambassador);
      }
    }
    apiSchoolDTO.setCampusAmbassadors(filteredList);
    ApiSchoolZhVO apiSchoolZhVO = BeanDtoVoUtil.convert(apiSchoolDTO, ApiSchoolZhVO.class);
    // 处理 collegeCharacteristics 字段
    if (apiSchoolDTO.getCollegeCharacteristics() != null) {
      List<String> processedCharacteristics = apiSchoolDTO.getCollegeCharacteristics().stream()
        .flatMap(original -> Arrays.stream(original.split("[,、]")))
        .map(String::trim)
        .filter(s -> !s.isEmpty())
        .collect(Collectors.toList());
      apiSchoolZhVO.setCollegeCharacteristics(processedCharacteristics);
    } else {
      apiSchoolZhVO.setCollegeCharacteristics(new ArrayList<>());
    }
    apiSchoolZhVO.setCulturalActivitiesSchoolBadge(BeanDtoVoUtil.listVo(apiSchoolDTO.getCulturalActivitiesSchoolBadge(), ApiSchoolZhVO.CulturalActivity.class));
    // 校园大使手动递归转换，保证类型安全
    List<ApiSchoolZhVO.CampusAmbassador> voAmbassadors = new ArrayList<>();
    if (apiSchoolDTO.getCampusAmbassadors() != null) {
      for (ApiSchoolDTO.CampusAmbassador dtoAmbassador : apiSchoolDTO.getCampusAmbassadors()) {
        ApiSchoolZhVO.CampusAmbassador voAmbassador = new ApiSchoolZhVO.CampusAmbassador();
        org.springframework.beans.BeanUtils.copyProperties(dtoAmbassador, voAmbassador);
        // 手动转换 worksUrl
        List<ApiSchoolZhVO.CampusAmbassador.Work> voWorks = new ArrayList<>();
        if (dtoAmbassador.getWorksUrl() != null) {
          for (ApiSchoolDTO.CampusAmbassador.Work dtoWork : dtoAmbassador.getWorksUrl()) {
            ApiSchoolZhVO.CampusAmbassador.Work voWork = new ApiSchoolZhVO.CampusAmbassador.Work();
            org.springframework.beans.BeanUtils.copyProperties(dtoWork, voWork);
            // opusList处理
            if (dtoWork.getOpusUrl() != null && !dtoWork.getOpusUrl().isEmpty()) {
              voWork.setOpusList(Arrays.asList(dtoWork.getOpusUrl().split(",")));
            } else {
              voWork.setOpusList(Collections.emptyList());
            }
            voWorks.add(voWork);
          }
        }
        voAmbassador.setWorksUrl(voWorks);
        voAmbassadors.add(voAmbassador);
      }
    }
    apiSchoolZhVO.setCampusAmbassadors(voAmbassadors);

    // 周边大赛手动递归转换，保证类型安全
    List<ApiSchoolZhVO.CulturalActivity> voSurroundings = new ArrayList<>();
    if (apiSchoolDTO.getCulturalActivitiesSurroundings() != null) {
      for (ApiSchoolDTO.CulturalActivity dtoActivity : apiSchoolDTO.getCulturalActivitiesSurroundings()) {
        ApiSchoolZhVO.CulturalActivity voActivity = new ApiSchoolZhVO.CulturalActivity();
        org.springframework.beans.BeanUtils.copyProperties(dtoActivity, voActivity);
        if (dtoActivity.getOpusUrl() != null && !dtoActivity.getOpusUrl().isEmpty()) {
          voActivity.setOpusList(Arrays.asList(dtoActivity.getOpusUrl().split(",")));
        } else {
          voActivity.setOpusList(Collections.emptyList());
        }
        voSurroundings.add(voActivity);
      }
    }
    apiSchoolZhVO.setCulturalActivitiesSurroundings(voSurroundings);
    // 处理 schoolBadgeOfficial 和 websiteOfficialImage 字段
    List<String> schoolBadgeOfficial = apiSchoolDTO.getSchoolBadgeOfficial();
    if (schoolBadgeOfficial != null) {
      schoolBadgeOfficial.removeIf(item -> item == null || item.isEmpty());
    } else {
      schoolBadgeOfficial = new ArrayList<>();
    }
    apiSchoolZhVO.setSchoolBadgeOfficial(schoolBadgeOfficial);

    List<String> websiteOfficialImage = apiSchoolDTO.getWebsiteOfficialImage();
    if (websiteOfficialImage != null) {
      websiteOfficialImage.removeIf(item -> item == null || item.isEmpty());
    } else {
      websiteOfficialImage = new ArrayList<>();
    }
    apiSchoolZhVO.setWebsiteOfficialImage(websiteOfficialImage);
    return apiSchoolZhVO;
  }

  /**
   * 获取大学相关的所有信息（英文版）
   * 逻辑说明：
   * 1. 查询大学相关的所有信息（如校徽、官网、校园大使等），仅取第一个结果。
   * 2. 处理特征、活动、校徽等字段，去除空值，组装VO返回。
   *
   * @param dto 查询参数
   * @return ApiSchoolEnVO 大学信息（英文）
   */
  @Override
  public ApiSchoolEnVO getSchoolInfoEn(ApiSchoolDTO dto) {
    List<ApiSchoolDTO> dtolist = schoolMapper.selectSchoolApiEn(dto);
    if (dtolist.isEmpty()) {
      return null;
    }
    // 只取第一个结果
    ApiSchoolDTO apiSchoolDTO = dtolist.get(0);
    ApiSchoolEnVO apiSchoolEnVO = BeanDtoVoUtil.convert(apiSchoolDTO, ApiSchoolEnVO.class);
    // 处理 collegeCharacteristics 字段
    if (apiSchoolDTO.getCollegeCharacteristicsEn() != null) {
      List<String> processedCharacteristicsEn = apiSchoolDTO.getCollegeCharacteristicsEn().stream()
        .flatMap(original -> Arrays.stream(original.split("[,、]")))
        .map(String::trim)
        .filter(s -> !s.isEmpty())
        .collect(Collectors.toList());
      apiSchoolEnVO.setCollegeCharacteristicsEn(processedCharacteristicsEn);
    } else {
      apiSchoolEnVO.setCollegeCharacteristicsEn(new ArrayList<>());
    }
    // 处理 schoolBadgeOfficial 和 websiteOfficialImage 字段
    List<String> schoolBadgeOfficial = apiSchoolDTO.getSchoolBadgeOfficial();
    if (schoolBadgeOfficial != null) {
      schoolBadgeOfficial.removeIf(Objects::isNull);
    } else {
      schoolBadgeOfficial = new ArrayList<>();
    }
    apiSchoolEnVO.setSchoolBadgeOfficial(schoolBadgeOfficial);
    List<String> websiteOfficialImage = apiSchoolDTO.getWebsiteOfficialImage();
    if (websiteOfficialImage != null) {
      websiteOfficialImage.removeIf(Objects::isNull);
    } else {
      websiteOfficialImage = new ArrayList<>();
    }
    apiSchoolEnVO.setWebsiteOfficialImage(websiteOfficialImage);

    // 校园大使手动递归转换，保证类型安全
    List<ApiSchoolEnVO.CampusAmbassador> voAmbassadors = new ArrayList<>();
    if (apiSchoolDTO.getCampusAmbassadors() != null) {
      for (ApiSchoolDTO.CampusAmbassador dtoAmbassador : apiSchoolDTO.getCampusAmbassadors()) {
        ApiSchoolEnVO.CampusAmbassador voAmbassador = new ApiSchoolEnVO.CampusAmbassador();
        org.springframework.beans.BeanUtils.copyProperties(dtoAmbassador, voAmbassador);
        // 手动转换 worksUrl
        List<ApiSchoolEnVO.CampusAmbassador.Work> voWorks = new ArrayList<>();
        if (dtoAmbassador.getWorksUrl() != null) {
          for (ApiSchoolDTO.CampusAmbassador.Work dtoWork : dtoAmbassador.getWorksUrl()) {
            ApiSchoolEnVO.CampusAmbassador.Work voWork = new ApiSchoolEnVO.CampusAmbassador.Work();
            org.springframework.beans.BeanUtils.copyProperties(dtoWork, voWork);
            // opusList处理
            if (dtoWork.getOpusUrl() != null && !dtoWork.getOpusUrl().isEmpty()) {
              voWork.setOpusList(Arrays.asList(dtoWork.getOpusUrl().split(",")));
            } else {
              voWork.setOpusList(Collections.emptyList());
            }
            voWorks.add(voWork);
          }
        }
        voAmbassador.setWorksUrl(voWorks);
        voAmbassadors.add(voAmbassador);
      }
    }
    apiSchoolEnVO.setCampusAmbassadors(voAmbassadors);

    // 周边大赛手动递归转换，保证类型安全
    List<ApiSchoolEnVO.CulturalActivity> voSurroundings = new ArrayList<>();
    if (apiSchoolDTO.getCulturalActivitiesSurroundings() != null) {
      for (ApiSchoolDTO.CulturalActivity dtoActivity : apiSchoolDTO.getCulturalActivitiesSurroundings()) {
        ApiSchoolEnVO.CulturalActivity voActivity = new ApiSchoolEnVO.CulturalActivity();
        org.springframework.beans.BeanUtils.copyProperties(dtoActivity, voActivity);
        if (dtoActivity.getOpusUrl() != null && !dtoActivity.getOpusUrl().isEmpty()) {
          voActivity.setOpusList(Arrays.asList(dtoActivity.getOpusUrl().split(",")));
        } else {
          voActivity.setOpusList(Collections.emptyList());
        }
        voSurroundings.add(voActivity);
      }
    }
    apiSchoolEnVO.setCulturalActivitiesSurroundings(voSurroundings);

    return apiSchoolEnVO;
  }

  /**
   * 统计校徽总数
   * 逻辑说明：
   * 1. 根据dto参数统计校徽总数。
   *
   * @param dto 查询参数
   * @return int 校徽总数
   */
  @Override
  public int countSchoolBadgeOfficial(SchoolOfficialDTO dto) {
    if (dto.getCharacteristic().equals("全部") || dto.getCharacteristic().equals("All")){
      dto.setCharacteristic("");
    }
    if (dto.getLevel().equals("全部") || dto.getLevel().equals("All")){
      dto.setLevel("");
    }
    return schoolMapper.countSchoolBadgeOfficial(dto);
  }

}
